/*Copyright (C) 2009 - 2011 Careil Baptiste

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include "../headers.h"

/* Permet de copier un fichier.
*/
int fichier_cpy(FILE *dest_file, FILE *orig_file) {
	char buffer[1024];
	size_t nb_bytes_read;

	do {
		nb_bytes_read = fread(buffer, sizeof(char), 1024, orig_file);

		if(nb_bytes_read > 0) {
			fwrite(buffer, sizeof(char), nb_bytes_read, dest_file);
		}
	}
	while(!feof(orig_file) && !ferror(orig_file) && !ferror(dest_file));

	if(!feof(orig_file)) {
		return 1;
	}

	return 0;
}

/* Permet de copier un nombre de lignes `nb_lines' depuis le
** fichier `orig' dans le fichier `dest'. La position dans les
** fichiers est inchangée avant l'oppération.
*/
int fichier_cpy_n_lines(FILE *dest, FILE *orig, int nb_lines) {
	char buffer[256];
	bool abort = false;
	int nb_lines_cpy = 1;

	while(nb_lines_cpy <= nb_lines && abort == false) {
		if(fgets(buffer, 256, orig) == NULL) {
			abort = true;
		}
		else {
			if(fputs(buffer, dest) == EOF) {
				abort = true;
			}
			else {
				if(strchr(buffer, '\n') != NULL) {
					nb_lines_cpy++;
				}
			}
		}
	}

	if(abort) {
		return -1;
	}

	return 0;
}

/* Permet de remplacer une portion d'un fichier à partir d'un autre.
*/
int fichier_merge(const char *dest, const char *orig, const char *patch, int line, bool insert) {
	FILE *dest_file, *orig_file;
	char buffer[256];
	bool abort = false;
	int nb_lines;

	orig_file = fopen(orig, "r");
	dest_file = fopen(dest, "w+");

	if(orig_file == NULL || dest_file == NULL) {
		if(orig_file) {
			fclose(orig_file);
		}

		if(dest_file) {
			fclose(dest_file);
		}

		return -1;
	}

	if(line) {
		if(fichier_cpy_n_lines(dest_file, orig_file, line)) {
			fclose(dest_file);
			fclose(orig_file);
			return -1;
		}
	}

	if(fputs(patch, dest_file) == EOF) {
		abort = true;
	}
	if(!insert) {
		nb_lines = str_count(patch, '\n');
		while(nb_lines && !abort) {
			if(fichier_goto_next_line(orig_file)) {
				abort = true;
			}
			nb_lines--;
		}
		Log_full(LOG_DEFAULT, "files.c:fichier_merge(), str_count(patch, '\\n')", str_count(patch, '\n'));
	}

	if(abort) {
		fclose(dest_file);
		fclose(orig_file);
		return -1;
	}

	if(patch[strlen(patch) - 1] != '\n') {
		fputc('\n', dest_file);
	}

	while(fgets(buffer, 256, orig_file) != NULL && !abort) {
		if(fputs(buffer, dest_file) == EOF) {
			abort = true;
		}
	}

	fclose(orig_file);
	fclose(dest_file);

	if(abort) {
		return -1;
	}

	return 0;
}

/* Permet de se déplacer à la ligne voulue. Le fichier
** est "rewind" avant l'oppération.
*/
int fichier_goto_line(FILE *file, int line) {
	char buffer[256];
	int nb_lines_read = 0;
	bool abort = false;

	if(fseek(file, 0, SEEK_SET)) {
		abort = true;
	}

	while(nb_lines_read < line && !abort) {
		if(fgets(buffer, 256, file) == NULL) {
			abort = true;
		}
		nb_lines_read += str_count(buffer, '\n');
	}

	if(abort) {
		return -1;
	}

	return 0;
}

/* Permet de se déplacer à la ligne suivante.
*/
int fichier_goto_next_line(FILE *file) {
	char buffer[256];
	bool loop = true;

	while(loop) {
		if(fgets(buffer, 256, file) == NULL) {
			loop = false;
		}
		else {
			if(strchr(buffer, '\n') != NULL) {
				loop = false;
			}
		}
	}

	if(feof(file) || ferror(file)) {
		return -1;
	}
	return 0;
}

/* Récupère la valeur du caractère à la position indiquée.
** La position dans le fichier vaut `offset' + 1 après
** l'opération s'il n'y a pas d'erreur.
*/
char fichier_get_char(FILE *file, long offset, int origin) {
	long save_pos;
	char read;

	save_pos = ftell(file);

	if(save_pos < 0) {
		return EOF;
	}

	if(fseek(file, offset, origin)) {
		return EOF;
	}

	if(!fread(&read, sizeof(char), 1, file)) {
		return EOF;
	}

	if(fseek(file, save_pos, SEEK_SET)) {
		return EOF;
	}

	printf("read : %i, '\\n' : %i\n", read, '\n');
	return read;
}

/* Vérifie la présence d'un fichier.
*/
bool fichier_existe(const char *filename) {
	FILE *file;
	bool retval = false;

	file = fopen(filename, "r");

	if(file != NULL) {
		fclose(file);
		retval = true;
	}

	return retval;
}

/* Crée un fichier.
*/
int fichier_creer(const char *filename) {
	FILE *file;
	int retval = 1;

	file = fopen(filename, "w");

	if(file != NULL) {
		fclose(file);
		retval = 0;
	}

	return retval;
}

/* Crée un dossier.
*/
bool new_folder(const char *folder) {
#ifdef WIN32
	if(_mkdir(folder) != 0)
#else
	if(mkdir(folder, 0755) != 0)
#endif
	{
		return false;
	}
	return true;
}

/* Vérifie la présence d'un dossier.
*/
bool existe_folder(const char *folder) {
	char chemin[200];

	sprintf(chemin, "%s/test.tmp", folder);

	if(!fichier_creer(chemin)) {
		remove(chemin);
		return true;
	}
	else {
		return false;
	}
}


